"""
部署管理API端点
"""
from typing import Any, List
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session

from app.core.database import get_db
from app.models.deployment import Deployment, DeploymentHistory
from app.models.user import User
from app.schemas.deployment import Deployment as DeploymentSchema, DeploymentCreate, DeploymentUpdate, DeploymentHistory as DeploymentHistorySchema
from app.api.endpoints.auth import get_current_user

router = APIRouter()


@router.get("/", response_model=List[DeploymentSchema])
async def get_deployments(
    skip: int = 0,
    limit: int = 100,
    application_id: int = None,
    environment_id: int = None,
    status: str = None,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
) -> Any:
    """获取部署列表"""
    query = db.query(Deployment)
    
    if application_id:
        query = query.filter(Deployment.application_id == application_id)
    if environment_id:
        query = query.filter(Deployment.environment_id == environment_id)
    if status:
        query = query.filter(Deployment.status == status)
    
    deployments = query.offset(skip).limit(limit).all()
    return deployments


@router.get("/{deployment_id}", response_model=DeploymentSchema)
async def get_deployment(
    deployment_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
) -> Any:
    """获取部署详情"""
    deployment = db.query(Deployment).filter(Deployment.id == deployment_id).first()
    if not deployment:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="部署不存在"
        )
    return deployment


@router.post("/", response_model=DeploymentSchema)
async def create_deployment(
    deployment_in: DeploymentCreate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
) -> Any:
    """创建部署"""
    # 验证应用是否存在
    from app.models.application import Application
    application = db.query(Application).filter(Application.id == deployment_in.application_id).first()
    if not application:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="应用不存在"
        )
    
    # 验证环境是否存在
    from app.models.environment import Environment
    environment = db.query(Environment).filter(Environment.id == deployment_in.environment_id).first()
    if not environment:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="环境不存在"
        )
    
    # 创建部署
    deployment = Deployment(
        **deployment_in.dict(),
        creator_id=current_user.id,
        status="pending"
    )
    db.add(deployment)
    db.commit()
    db.refresh(deployment)
    
    # TODO: 启动部署任务
    # start_deployment_task.delay(deployment.id)
    
    return deployment


@router.put("/{deployment_id}", response_model=DeploymentSchema)
async def update_deployment(
    deployment_id: int,
    deployment_in: DeploymentUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
) -> Any:
    """更新部署"""
    deployment = db.query(Deployment).filter(Deployment.id == deployment_id).first()
    if not deployment:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="部署不存在"
        )
    
    # 更新部署信息
    update_data = deployment_in.dict(exclude_unset=True)
    for field, value in update_data.items():
        setattr(deployment, field, value)
    
    db.commit()
    db.refresh(deployment)
    
    return deployment


@router.post("/{deployment_id}/start")
async def start_deployment(
    deployment_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
) -> Any:
    """启动部署"""
    deployment = db.query(Deployment).filter(Deployment.id == deployment_id).first()
    if not deployment:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="部署不存在"
        )
    
    if deployment.status != "pending":
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="部署状态不允许启动"
        )
    
    # 更新部署状态
    deployment.status = "running"
    deployment.started_at = datetime.utcnow()
    db.commit()
    
    # TODO: 启动部署任务
    # start_deployment_task.delay(deployment.id)
    
    return {"message": "部署已启动"}


@router.post("/{deployment_id}/stop")
async def stop_deployment(
    deployment_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
) -> Any:
    """停止部署"""
    deployment = db.query(Deployment).filter(Deployment.id == deployment_id).first()
    if not deployment:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="部署不存在"
        )
    
    if deployment.status not in ["running", "pending"]:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="部署状态不允许停止"
        )
    
    # 更新部署状态
    deployment.status = "cancelled"
    deployment.completed_at = datetime.utcnow()
    db.commit()
    
    # TODO: 停止部署任务
    # stop_deployment_task.delay(deployment.id)
    
    return {"message": "部署已停止"}


@router.post("/{deployment_id}/rollback")
async def rollback_deployment(
    deployment_id: int,
    target_version: str = None,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
) -> Any:
    """回滚部署"""
    deployment = db.query(Deployment).filter(Deployment.id == deployment_id).first()
    if not deployment:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="部署不存在"
        )
    
    # 创建回滚部署
    rollback_deployment = Deployment(
        name=f"{deployment.name}-rollback",
        version=target_version or "previous",
        deployment_type=deployment.deployment_type,
        strategy=deployment.strategy,
        config=deployment.config,
        application_id=deployment.application_id,
        environment_id=deployment.environment_id,
        creator_id=current_user.id,
        status="pending"
    )
    db.add(rollback_deployment)
    db.commit()
    db.refresh(rollback_deployment)
    
    # TODO: 启动回滚任务
    # start_rollback_task.delay(rollback_deployment.id, deployment_id)
    
    return {"message": "回滚已启动", "rollback_deployment_id": rollback_deployment.id}


@router.get("/{deployment_id}/history", response_model=List[DeploymentHistorySchema])
async def get_deployment_history(
    deployment_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
) -> Any:
    """获取部署历史"""
    deployment = db.query(Deployment).filter(Deployment.id == deployment_id).first()
    if not deployment:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="部署不存在"
        )
    
    history = db.query(DeploymentHistory).filter(
        DeploymentHistory.deployment_id == deployment_id
    ).order_by(DeploymentHistory.created_at.desc()).all()
    
    return history


@router.get("/{deployment_id}/logs")
async def get_deployment_logs(
    deployment_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
) -> Any:
    """获取部署日志"""
    deployment = db.query(Deployment).filter(Deployment.id == deployment_id).first()
    if not deployment:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="部署不存在"
        )
    
    return {
        "deployment_id": deployment_id,
        "logs": deployment.logs or "",
        "status": deployment.status
    }
